package dev.ideas.funkyj.group;

import dev.ideas.funkyj.function.F;
import dev.ideas.funkyj.function.F2;
import dev.ideas.funkyj.sequence.Sequence;
import dev.ideas.funkyj.tuple.Single;

import java.util.*;

import static dev.ideas.funkyj.sequence.Sequence.from;

/**
 */
public class Group2<G2, G1, T> extends _Group.Node<G2, Group1<G1, T>, T> {
    private final F<T, G2> f2;
    private final F<T, G1> f1;

    public Group2(Iterator<T> iterator, F<T, G2> f2, F<T, G1> f1) { super(iterator); this.f1 = f1; this.f2 = f2; }
    Group2(_Group.Root<T> root, F<T, G2> f2, F<T, G1> f1) { super(root); this.f1 = f1; this.f2 = f2; }

    @Override G2 key(T t) { return f2.apply(t); }
    @Override Group1<G1, T> create() { return new Group1<G1, T>(root, f1); }

    public Group1<G1, T> select(final G2 g2) { return get(g2); }
    public Sequence<T> select(final G2 g2, final G1 g1) { return select(g2).select(g1); }

    //
    /* to reduce */
    public Group<G2, Group<G1, Single<T>>> to(final F2<T, T, T> f) {
        return new Group<G2, Group<G1, Single<T>>>() {
            @Override public Group<G1, Single<T>> select(G2 g2) {
                return Group2.this.select(g2).to(f);
            }
        };
    }
}